package hehe.router.util;

import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 路由帮助类
 *<B>说明：</B>
 *<pre>
 * 略
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  略
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class RouteHelper
{
    /**
     * 去掉指定字符串的开头和结尾的指定字符
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param stream 要处理的字符串
     * @param trimstr 要去掉的字符串
     */
    public static String trim(String stream, String trimstr)
    {

        // null或者空字符串的时候不处理
        if (stream == null || stream.length() == 0 || trimstr == null || trimstr.length() == 0) {
            return stream;
        }

        // 结束位置
        int epos = 0;

        // 正规表达式
        String regpattern = "[" + trimstr + "]*+";
        Pattern pattern = Pattern.compile(regpattern, Pattern.CASE_INSENSITIVE);

        // 去掉结尾的指定字符
        StringBuffer buffer = new StringBuffer(stream).reverse();
        Matcher matcher = pattern.matcher(buffer);
        if (matcher.lookingAt()) {
            epos = matcher.end();
            stream = new StringBuffer(buffer.substring(epos)).reverse().toString();
        }

        // 去掉开头的指定字符
        matcher = pattern.matcher(stream);
        if (matcher.lookingAt()) {
            epos = matcher.end();
            stream = stream.substring(epos);
        }

        return stream;
    }

    /**
     * 去掉指定字符串的结尾的指定字符
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param stream 要处理的字符串
     * @param trimstr 要去掉的字符串
     */
    public static String rtrim(String stream, String trimstr)
    {
        // null或者空字符串的时候不处理
        if (stream == null || stream.length() == 0 || trimstr == null || trimstr.length() == 0) {
            return stream;
        }

        // 结束位置
        int epos = 0;

        // 正规表达式
        String regpattern = "[" + trimstr + "]*+";
        Pattern pattern = Pattern.compile(regpattern, Pattern.CASE_INSENSITIVE);

        // 去掉结尾的指定字符
        StringBuffer buffer = new StringBuffer(stream).reverse();
        Matcher matcher = pattern.matcher(buffer);
        if (matcher.lookingAt()) {
            epos = matcher.end();
            stream = new StringBuffer(buffer.substring(epos)).reverse().toString();
        }

        return stream;
    }

    /**
     * 替换map 参数
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param target 替换目标
     * @param params 替换参数
     */
    public static String replaceMap(String target,Map<String,String> params)
    {
        String targetTemp = target;
        for (Map.Entry<String, String> param : params.entrySet()) {
            targetTemp = targetTemp.replaceAll(param.getKey(),param.getValue());
        }

        return targetTemp;
    }

    /**
     * 获取Matcher匹配的分组参数
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param matcher 替换目标
     * @param datas 替换参数
     */
    public static Map<String,String> getMatcherParams(Matcher matcher,Map<String,String> datas)
    {
        Map<String,String> params = new HashMap<>();
        String name,groupValue;
        for (Map.Entry<String, String> data : datas.entrySet()) {
            name = data.getKey();
            groupValue = matcher.group(name);
            if (groupValue != null) {
                params.put(name,groupValue);
            }
        }

        return params;
    }

    /**
     * 数组转LinkedList类型
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static <T> List<T>  arrayToLinkedList(T[] arr)
    {
        List<T> linkedList = new LinkedList<>();

        for (T one : arr) {
            linkedList.add(one);
        }

        return linkedList;
    }

    /**
     * 首字母大小
     *<B>说明：</B>
     *<pre>
     * 属性详细描述
     *</pre>
     */
    public static String upperCase(String str)
    {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }

        return new String(ch);
    }

    /** 以下为　设置对象属性相关方法*/

    /**
     * 字段定义缓存列表
     *<B>说明：</B>
     *<pre>
     * 通过反射获取Field对象后缓存于此
     *</pre>
     */
    private static final Map<Class<?>,Map<String,Field>> declaredFieldsCache =
            new HashMap<>();

    /**
     * 设置对象属性值
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param object 属性名
     * @param attrs 对象
     */
    public static void setAttrs(Object object,Map<String,Object> attrs)
    {
        Class clazz = object.getClass();
        String fieldName;
        Field field;
        Map<String,Field> fields = getFields(clazz);
        if (fields.size() == 0) {
            return;
        }

        for (Map.Entry<String, Object> attr : attrs.entrySet()) {
            try {
                fieldName = attr.getKey();
                if (fields.containsKey(fieldName)) {
                    field = fields.get(fieldName);
                    field.setAccessible(true);
                    field.set(object,attr.getValue());
                }
            } catch (Exception e) {
                // 不做任何事情
            }
        }
    }

    /**
     * 获取类全部字段
     *<B>说明：</B>
     *<pre>
     * 方法详细描述
     *</pre>
     */
    public static Map<String,Field> getFields(Class<?> clazz)
    {

        if (!declaredFieldsCache.containsKey(clazz)) {
            // 重新读取
            Map<String,Field> fields = getDeclaredFields(clazz);
            declaredFieldsCache.put(clazz,fields.size() > 0 ? fields : new HashMap());
        }

        return declaredFieldsCache.get(clazz);
    }

    /**
     * 获取类全部字段
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @return 未找道属性则，返回null
     */
    public static Map<String,Field> getDeclaredFields(Class<?> clazz)
    {
        Map<String,Field> clazzFields = new HashMap<>();
        List<Class> superClazzs = findSuperclass(clazz);
        Collections.reverse(superClazzs);

        for (Class<?> superClazz : superClazzs) {
            Field[] fields = superClazz.getDeclaredFields() ;
            for (Field field : fields) {
                clazzFields.put(field.getName(),field);
            }
        }

        return clazzFields;
    }

    /**
     * 查找对应父类
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    public static List<Class> findSuperclass(Class<?> clazz)
    {

        Class<?> targetClazz = clazz;
        List<Class> superClazzs = new ArrayList<>();
        superClazzs.add(clazz);

        while (true) {//当父类为null的时候说明到达了最上层的父类(Object类).
            targetClazz = targetClazz.getSuperclass(); //得到父类,然后赋给自己
            if (targetClazz != null && targetClazz != Object.class) {
                superClazzs.add(targetClazz);
            } else {
                break;
            }
        }

        return superClazzs;
    }
}
